package com.zhai.boot.controller;

import com.zhai.boot.annotation.CacheLock;
import com.zhai.boot.annotation.ControllerLog;
import com.zhai.boot.annotation.LimitStream;
import com.zhai.boot.annotation.TrimMethod;
import com.zhai.boot.async.log.BizLogAsync;
import com.zhai.boot.async.log.BizLogConstant;
import com.zhai.boot.async.log.BizLogInOut;
import com.zhai.boot.async.log.BizLogUtil;
import com.zhai.boot.common.ServiceResult;
import com.zhai.boot.domain.in.DemoFindIn;
import com.zhai.boot.domain.in.DemoLogIn;
import com.zhai.boot.domain.in.DemoSaveIn;
import com.zhai.boot.domain.in.TrimDataIn;
import com.zhai.boot.service.DemoService;
import com.zhai.boot.util.JSONUtil;
import com.zhai.boot.util.ListUtil;
import com.zhai.boot.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * @package: com.zhai.boot.controller
 * @project-name: zhai-boot
 * @description: 示例controller
 * @author: Created by 翟凤玺
 * @create-datetime: 2018-7-10 11:42
 */
@Api("Demo接口")
@RestController
@RequestMapping("/demo")
public class DemoController {

    @Autowired
    private DemoService demoService;

    @CacheLock(prefix = "demo:save", expire = 10L)
    @ApiOperation(value="保存demo信息", notes="就是保存demo信息")
    @ApiImplicitParam(name = "in", dataType = "DemoSaveIn", value = "demo保存的入参", required = true, paramType = "body")
    @PostMapping("/save")
    public ResponseEntity save(@RequestBody @Validated DemoSaveIn in) {
        if (ListUtil.isNotEquals(DemoSaveIn.PARAMS_HOBBY, in.getHobby())) {
            return ResponseEntity.ok(ServiceResult.failure(DemoSaveIn.ERROR_CODE_PARAMS_HOBBY, DemoSaveIn.ERROR_MESSAGE_PARAMS_HOBBY));
        }
        ServiceResult<Object> result = demoService.save(in);
        return ResponseEntity.ok().body(ServiceResult.defined(result));
    }


    @ControllerLog(mongo="controller_log_demo", operate="查询demo信息", remark = "开发中")
    @ApiOperation(value="查询demo信息", notes="根据条件查询demo信息")
    @ApiImplicitParam(name = "in", dataType = "DemoFindIn", value = "demo查询的入参", required = true, paramType = "body")
    @PostMapping("/find")
    public ResponseEntity find(@RequestBody @Validated DemoFindIn in) {
        ServiceResult<Object> result = demoService.find(in);
        return ResponseEntity.ok().body(ServiceResult.defined(result));
    }

    @ApiOperation(value="查询demo信息", notes="根据条件查询demo信息")
    @PostMapping("/grid")
    public ResponseEntity grid() {
        ServiceResult<Object> result = demoService.grid();
        return ResponseEntity.ok().body(ServiceResult.defined(result));
    }

    @LimitStream(prefix = "demo:getById", period = 100, count = 2)
    @ApiOperation(value="id查询信息", notes="根据id查询信息")
    @ApiImplicitParam(name = "id", dataType = "String", value = "主键", required = true, paramType = "path")
    @GetMapping("/get/{id}")
    public ResponseEntity getById(@PathVariable("id") String id) {
        ServiceResult<Object> result = demoService.getById(id);
        return ResponseEntity.ok().body(ServiceResult.defined(result));
    }

    @Resource
    private RedissonClient redissonClient;

    @ApiOperation(value="锁", notes="锁")
    @GetMapping("/redisson-lock")
    public String lock() {
        // 1.获取分布式锁
        RLock lock = redissonClient.getLock("my:lock");
        // 2.进行加锁操作
        lock.lock();
        System.out.println(LocalDateTime.now() + " lock locked");
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
            Thread.currentThread().interrupt();
        } finally {
            // 3.释放锁资源
            lock.unlock();
            System.out.println(LocalDateTime.now() + "lock unlocked");
        }
        return "lock";
    }


    @TrimMethod
    @PostMapping("/trim")
    public ResponseEntity trim(@RequestBody @Validated TrimDataIn in) {
        return ResponseEntity.ok().body(ServiceResult.failure("-1", JSONUtil.toStr(in)));
    }

    @ApiOperation(value="查询demo信息", notes="根据条件查询demo信息")
    @PostMapping("/log")
    public ResponseEntity log(@RequestBody DemoLogIn in) {
        ServiceResult result = demoService.log(in);
        return ResponseEntity.ok().body(ServiceResult.defined(result));
    }
}
